<template>
    <div class="page-wrap">
        <!-- 顶部条 -->
        <div class="topbar" ref="topbarRef">
            <div class="grow">
                <a-input v-model:value="keyword" :allow-clear="true" placeholder="输入关键字查询" style="max-width: 320px">
                    <template #prefix>
                        <SearchOutlined />
                    </template>
                </a-input>
                <a-button type="primary" class="ml8" @click="onSearch">查询</a-button>
            </div>

            <div class="current-node">
                <span>当前节点：</span>
                <a-select v-model:value="node" style="width: 160px">
                    <a-select-option value="all">所有节点</a-select-option>
                    <a-select-option value="haerbinun">haerbinun</a-select-option>
                    <a-select-option value="infocf">infocf</a-select-option>
                    <a-select-option value="xibu">xibu</a-select-option>
                </a-select>
            </div>

            <div class="right-tools">
                <a-button type="primary" @click="onCreate">新增</a-button>
            </div>
        </div>

        <!-- 表格卡片 -->
        <div class="card" ref="cardRef">
            <div class="table-pane">
                <a-table :columns="columns" :data-source="pageData" :loading="loading" row-key="id"
                    :row-selection="rowSelection" :pagination="false" :scroll="{ x: 1280 }">
                    <template #bodyCell="{ column, record }">
                        <template v-if="column.key === 'appName'">
                            <a class="ellipsis text-black" @click="openApp(record)">{{ record.appName }}</a>
                        </template>

                        <template v-else-if="column.key === 'indexName'">
                            <a class="ellipsis text-black" @click="openIndex(record)">{{ record.indexName }}</a>
                            <span v-if="record.indexCount !== undefined">（{{ record.indexCount }}）</span>
                        </template>

                        <template v-else-if="column.key === 'status'">
                            <span class="status-dot" :class="record.status === 'ok' ? 'status-green' : 'status-red'"
                                :title="record.status === 'ok' ? '运行中' : '异常'" />
                        </template>

                        <template v-else-if="column.key === 'actions'">
                            <span class="op-links">
                                <a class="link" @click="onEdit(record)">编辑</a>
                                <a-divider type="vertical" />
                                <a class="link" @click="onDelete(record)">删除</a>
                                <a-divider type="vertical" />
                                <a class="link" @click="onConfig(record)">配置</a>
                            </span>
                        </template>
                    </template>
                </a-table>
            </div>

            <!-- 底部分页 -->
            <div class="footer-bar" ref="footerRef">
                <div class="right">
                    <span class="stat">已选 {{ selectedCount }} 条，共 {{ total }} 条。</span>
                    <a-pagination :current="current" :pageSize="pageSize" :total="total" show-less-items
                        @change="onPageChange" />
                    <a-select v-model:value="pageSize" style="width: 100px" @change="onPageSizeChange">
                        <a-select-option :value="10">10/页</a-select-option>
                        <a-select-option :value="20">20/页</a-select-option>
                        <a-select-option :value="50">50/页</a-select-option>
                    </a-select>
                </div>
            </div>
        </div>
    </div>
</template>

<script setup lang="ts">
import { computed, ref, watch, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { message, Modal } from 'ant-design-vue'
import type { TableColumnType } from 'ant-design-vue'
import { SearchOutlined } from '@ant-design/icons-vue'
import api from '@/api/api'

type Row = {
    id: number | string
    appName: string
    indexName: string
    indexCount?: number
    node: string
    unit: string
    status: 'ok' | 'down'
    createdAt: string
}

const router = useRouter()
const node = ref<'all' | string>('all')
const keyword = ref('')

const loading = ref(false)
const current = ref(1)
const pageSize = ref(10)
const total = ref(0)

const allData = ref<Row[]>([])
const pageData = computed<Row[]>(() => allData.value)

const columns = ref<TableColumnType[]>([
    { title: '应用名称', dataIndex: 'appName', key: 'appName', width: 220 },
    { title: '索引库', dataIndex: 'indexName', key: 'indexName', width: 240 },
    { title: '所属节点', dataIndex: 'node', width: 140, ellipsis: true },
    { title: '使用单位', dataIndex: 'unit', width: 160, ellipsis: true },
    { title: '状态', dataIndex: 'status', key: 'status', width: 80, align: 'center' },
    { title: '创建时间', dataIndex: 'createdAt', width: 180 },
    { title: '操作', key: 'actions', width: 180, fixed: 'right' }
])

const selectedRowKeys = ref<(number | string)[]>([])
const selectedCount = computed(() => selectedRowKeys.value.length)
const rowSelection = ref({
    selectedRowKeys: selectedRowKeys.value,
    onChange: (keys: (string | number)[]) => {
        selectedRowKeys.value = keys
        rowSelection.value.selectedRowKeys = selectedRowKeys.value
    }
})

function onSearch() {
    current.value = 1
    loadList()
}

function onCreate() { router.push({ path: '/searchApplicationPage' }) }
function onEdit(r: Row) { router.push({ path: '/searchApplicationPage', query: { id: String(r.id) } }) }
function openApp(r: Row) { }
function openIndex(r: Row) { }
function onConfig(r: Row) { message.info(`配置：${r.appName}`) }
function onDelete(r: Row) {
    Modal.confirm({
        title: `确认删除「${r.appName}」？`,
        okText: '删除',
        okButtonProps: { danger: true },
        onOk: async () => {
            try {
                await api.searchAppDelete({ id: r.id })
                message.success('删除成功')
                selectedRowKeys.value = []
                rowSelection.value.selectedRowKeys = selectedRowKeys.value
                if (allData.value.length === 1 && current.value > 1) current.value = current.value - 1
                await loadList()
            } catch (e: any) {
                message.error(e?.message || '删除失败')
                throw e
            }
        }
    })
}
function onPageChange(p: number) { current.value = p; loadList() }
function onPageSizeChange() { current.value = 1; loadList() }

async function initNodeByIdFromQuery() {
    const qid = router.currentRoute.value.query.id as string | undefined
    if (!qid) return
    try {
        const resp: any = await api.searchAppGetById({ id: qid })
        const record = (resp?.data ?? resp) as any
        const nodeName: string | undefined = record?.node_name ?? record?.node ?? record?.now_name
        if (nodeName) node.value = nodeName as any
    } catch { }
}

async function loadList() {
    try {
        loading.value = true
        const kw = keyword.value.trim()
        const params = {
            page: current.value,
            size: pageSize.value,
            now_name: node.value === 'all' ? undefined : node.value,
            app_name: kw === '' ? undefined : kw
        }
        const res: any = await api.searchAppPageList(params)
        const container: Record<string, any> =
            (res && typeof res === 'object' && 'data' in res ? res.data : res) || {}
        const listFromServer: any[] = Object.keys(container)
            .filter((k) => /^\d+$/.test(k))
            .sort((a, b) => Number(a) - Number(b))
            .map((k) => container[k])

        const rawTotal = container.total != null ? container.total : (res && res.total != null ? res.total : undefined)
        const totalFromServer = Number(rawTotal)
        total.value = Number.isFinite(totalFromServer) ? totalFromServer : listFromServer.length

        if (container.page != null) current.value = Number(container.page) || current.value
        if (container.page_size != null) pageSize.value = Number(container.page_size) || pageSize.value

        allData.value = listFromServer.map(mapRow)
    } catch (e: any) {
        message.error(e?.message || '加载失败')
    } finally {
        loading.value = false
    }
}

function mapRow(item: any): Row {
    const indexRaw = item.index_db_list ?? item.index_name ?? item.index ?? null
    let indexName = ''
    let indexCount: number | undefined = undefined
    if (Array.isArray(indexRaw)) { indexName = indexRaw.join(','); indexCount = indexRaw.length }
    else if (typeof indexRaw === 'string') indexName = indexRaw
    return {
        id: item.id,
        appName: item.app_name,
        indexName,
        indexCount,
        node: item.node_name,
        unit: item.unit_name,
        status: item.app_status === 'active' ? 'ok' : 'down',
        createdAt: item.create_time
    }
}

onMounted(async () => {
    await initNodeByIdFromQuery()
    await loadList()
})

watch(node, () => { current.value = 1; loadList() })
</script>

<style lang="less" scoped>
.page-wrap {
    min-height: 100vh;
    padding: 12px;
    background: #f5f7fa;
    display: flex;
    flex-direction: column;
}

/* 顶部条 */
.topbar {
    display: flex;
    align-items: center;
    gap: 12px;
    background: #fff;
    padding: 10px 12px;
    border: 1px solid #f0f0f0;
    border-radius: 4px;
}

.topbar .grow {
    flex: 1;
    display: flex;
    align-items: center;
}

/* 查询按钮的间距 */
.ml8 {
    margin-left: 8px;
}

.topbar .current-node {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: #666;
}

.topbar .right-tools {
    margin-left: auto;
    display: flex;
}

/* 卡片容器 */
.card {
    flex: 1;
    margin-top: 10px;
    background: #fff;
    border: 1px solid #f0f0f0;
    border-radius: 4px;
    display: flex;
    flex-direction: column;
    min-height: 0;
    position: relative;
    z-index: 0;
}

/* 表格区域 */
.table-pane {
    flex: 0 0 auto;

    min-height: 0;
    padding: 8px 12px 0;
    display: flex;
    flex-direction: column;
    padding-bottom: 0;
}

.table-pane :deep(.ant-table) {
    font-size: 14px;
}

/* 表头背景 #F4F8FD */
.table-pane :deep(.ant-table-thead > tr > th) {
    padding: 10px 12px;
    background: #F4F8FD;
}


.table-pane :deep(.ant-table-tbody > tr > td) {
    padding: 0 12px;
    height: 40px;
    line-height: 30px;
}


.table-pane :deep(.ant-table-body) {
    overflow: visible;
}

/* 底部分页 */
.footer-bar {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 10px;
    padding: 10px 12px;
    border-top: 1px solid #f0f0f0;
    background: #fff;
    position: static;
    bottom: auto;
    z-index: auto;
    box-shadow: none;
    margin-top: 8px;
}

.footer-bar .right {
    display: flex;
    align-items: center;
    gap: 10px;
}

.stat {
    color: #666;
}

/* 状态圆点 */
.status-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    display: inline-block;
}

.status-green {
    background: #52c41a;
}

.status-red {
    background: #ff4d4f;
}

/* 链接与操作 */
.link {
    color: #1677ff;
    cursor: pointer;
}

.text-black {
    color: #000 !important;
    cursor: pointer;
}

.op-links {
    display: inline-flex;
    gap: 8px;
}

.ellipsis {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 260px;
    display: inline-block;
}
</style>
